#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;

#include <vector>
#include <semaphore.h>

namespace server{
//类模板
template<class T>
class BlockQueue
{
public:
  BlockQueue(size_t s=1024)
    :_data(s),_head(0),_tail(0),_size(0)
  {
    sem_init(&sem_data,0,0);
    sem_init(&sem_blank,0,s);
  }
  ~BlockQueue()
  {
    sem_destroy(&sem_data);
    sem_destroy(&sem_blank);
  }
  //入队列
  void PushQueue(T& value)
  {
    sem_wait(&sem_blank);
    _data[_tail++]=value;
    if(_tail>=_data.size())
    {
      _tail=0;
    }
    _size++;
    sem_post(&sem_data);
  }
  //出队列
  void PopQueue(T* value)
  {
    sem_wait(&sem_data);
    *value=_data[_head++];
    if(_head>_data.size())
    {
      _head=0;
    }
    _size--;
    sem_post(&sem_blank);
  }
private:
  std::vector<T> _data;//使用数组来保存消息
  size_t _head;//队列头
  size_t _tail;//队列尾
  size_t _size;//队列中有效消息数
  sem_t sem_data;//记录可消费消息
  sem_t sem_blank;//记录可放消息的空间
  //因为是单生产者单消费者的阻塞队列
  //所以此处可以不加互斥锁sem_lock
};

}
